home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.misc
- From: bturner@hpcvxbt.cv.hp.com (Bill Turner)
- subject: v11i084: Four new PPM utilities
- Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
-
- Posting-number: Volume 11, Issue 84
- Submitted-by: bturner@hpcvxbt.cv.hp.com (Bill Turner)
- Archive-name: ppm-utils/part01
-
- After getting the PBMPLUS stuff, I found there were some things I'd still like
- to be able to do -- in particular, the pbm programs seemed weak at combining
- images together. Part of that is because I didn't read the documentation
- (yes, RTFM), but I didn't see a good way of "concatenating" images together.
- Also, since I enjoy tinkering with code, I wanted to see how the PBM code
- worked. Anyway, from this was born the following four programs: ppmfill,
- ppmborder, ppmmerge, and ppmoverlay.
-
- ppmfill is basically a subset of pnmtile (since it only works with ppm's).
- ppmborder writes a border around a ppmfile (could be done with pnmtile and
- pnmpaste, but I like the cleanliness of a single program).
- ppmmerge concatenates a number of ppm files together, either side by side or
- stacked vertically.
- ppmoverlay is similar to pnmpaste, with a different interface (specify border
- size and corner [i.e., top left] rather than (x, y) offset).
-
- Even if nobody finds these useful, I wrote 'em, so I'm submitting 'em!
-
- --Bill Turner (bturner@hp-pcd.cv.hp.com)
- Hewlett-Packard Information Technology Operation
-
- ---------------------------------cut here-------------------------------------
- #! /bin/sh
- #
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- #
- # Wrapped by Bill Turner <bturner@hp-pcd.cv.hp.com> on Mon Mar 19 14:11:26 1990
- #
- # This archive contains:
- # ppmfill.1 ppmborder.1 ppmmerge.1 ppmoverlay.1
- # ppmfill.c ppmborder.c ppmmerge.c ppmoverlay.c
- #
-
- LANG=""; export LANG
- PATH=/bin:/usr/bin:$PATH; export PATH
-
- echo x - ppmfill.1
- cat >ppmfill.1 <<'@EOF'
- .TH ppmfill 1 "19 March 1990"
- .SH NAME
- ppmfill - fill an area with a tiled ppm
- .SH SYNOPSIS
- pbmfill <width> <height> [ppmfile]
- .SH DESCRIPTION
- Produces a portable pixmap of the specified width and height,
- with a pattern in it. The specified ppmfile (or stdin, if no
- file is specified) is tiled to create a new ppmfile of the specified
- size.
- .SH "SEE ALSO"
- pnmtile(1), ppmborder(1), ppm(5)
-
- This was written without reading the ppm documentation, and is functionally a
- subset of pnmtile (since ppmfill only handles ppm's). But since I spent the
- time doing it, I'm damn well going to send it out!
- .SH AUTHOR
- Bill Turner, Hewlett-Packard Company. Since the work is heavily leveraged
- from the original PBM source, below is the original copyright notice.
-
- Copyright (C) 1989 by Jef Poskanzer.
-
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted, provided
- that the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation. This software is provided "as is" without express or
- implied warranty.
- @EOF
-
- chmod 644 ppmfill.1
-
- echo x - ppmborder.1
- cat >ppmborder.1 <<'@EOF'
- .TH ppmborder 1 "19 March 1990"
- .SH NAME
- ppmborder - add a border around a ppm file
- .SH SYNOPSIS
- ppmborder <width> <borderfile> [ppmfile]
- .SH DESCRIPTION
- Uses a tile of
- .I borderfile
- as a border around a ppmfile. The ppmfile produced is larger than the
- original.
- .I width
- specifies the width of the border to produce.
- .SH "SEE ALSO"
- pnmtile(1), ppmfill(1), ppm(5)
- .SH AUTHOR
- Bill Turner, Hewlett-Packard Company. Since the work is heavily leveraged
- from the original PBM source, below is the original copyright notice.
-
- Copyright (C) 1989 by Jef Poskanzer.
-
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted, provided
- that the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation. This software is provided "as is" without express or
- implied warranty.
- @EOF
-
- chmod 644 ppmborder.1
-
- echo x - ppmmerge.1
- cat >ppmmerge.1 <<'@EOF'
- .TH ppmmerge 1 "19 March 1990"
- .SH NAME
- ppmmerge - merge ppmfiles together
- .SH SYNOPSIS
- ppmmerge [-v | -h] ppmfile...
- .SH DESCRIPTION
- Concatenates the ppmfiles either side-by-side (
- .I -h
- , the default) or one on
- top of the other (
- .I -v
- ). Any number of ppm files may be specified, but it doesn't make much sense
- to have less than two.
- .PP
- This is useful for producing a "collection" image, where a number of images
- are merged into a single file.
- .SH "SEE ALSO"
- ppmoverlay(1), ppm(5)
- .SH AUTHOR
- Bill Turner, Hewlett-Packard Company. Since the work is heavily leveraged
- from the original PBM source, below is the original copyright notice.
-
- Copyright (C) 1989 by Jef Poskanzer.
-
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted, provided
- that the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation. This software is provided "as is" without express or
- implied warranty.
- @EOF
-
- chmod 644 ppmmerge.1
-
- echo x - ppmoverlay.1
- cat >ppmoverlay.1 <<'@EOF'
- .TH ppmoverlay 1 "19 March 1990"
- .SH NAME
- ppmoverlay - overlay one ppm over the top of another
- .SH SYNOPSIS
- ppmoverlay [-top|-vcenter|-bottom] [-left|-hcenter|-right] [-border #]
- ppmfile [ppmbackground]
- .SH DESCRIPTION
- Overlays a ppmfile over the specified background (or stdin, if no background
- file is specified). The default is to center the image over the background,
- but this may be overridden with the flags.
- .IP -top 10
- The image is placed along the top border.
- .IP -vcenter 10
- (Default) The image is centered vertically.
- .IP -bottom 10
- The image is placed along the bottom border.
- .IP -left 10
- The image is placed along the left border.
- .IP -hcenter 10
- (Default) The image is centered horizontally.
- .IP -right 10
- The image is placed along the right border.
- .IP -border 10
- Specifies the border width to use (default = 0).
- .PP
- If the source image is too small to fit on the background with the specified
- border width, an error message is generated.
- .PP
- This is useful for generating "collection" images.
- .SH "KNOWN PROBLEMS"
- The border width is used for both the vertical and horizontal borders. There
- is no way to specify separate border sizes (although this is an easy
- modification to make, and it should be done).
- .SH "SEE ALSO"
- pnmtile(1), ppmfill(1), ppm(5)
- .SH AUTHOR
- Bill Turner, Hewlett-Packard Company. Since the work is heavily leveraged
- from the original PBM source, below is the original copyright notice.
-
- Copyright (C) 1989 by Jef Poskanzer.
-
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted, provided
- that the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation. This software is provided "as is" without express or
- implied warranty.
- @EOF
-
- chmod 644 ppmoverlay.1
-
- echo x - ppmfill.c
- cat >ppmfill.c <<'@EOF'
- /* ppmfill - fill a rectangle with a tiling of a ppm file
- **
- ** Written 3/90 by Bill Turner, heavily leveraged from code by Jef Poskanzer,
- ** hence the copyright below.
- **
- ** Copyright (C) 1989 by Jef Poskanzer.
- **
- ** Permission to use, copy, modify, and distribute this software and its
- ** documentation for any purpose and without fee is hereby granted, provided
- ** that the above copyright notice appear in all copies and that both that
- ** copyright notice and this permission notice appear in supporting
- ** documentation. This software is provided "as is" without express or
- ** implied warranty.
- */
-
- #include <stdio.h>
- #include "ppm.h"
-
- main( argc, argv )
- int argc;
- char *argv[];
- {
- FILE *ifd;
- pixel **pixels, *newpixelrow;
- register pixel *sP, *dP;
- int argn, rows, cols, newrows, newcols, row, col, irow, icol;
- pixval maxval;
- char *usage = "width height [ppmfile]";
-
- pm_progname = argv[0];
-
- argn = 1;
-
- if ( argc < 3 )
- pm_usage( usage );
-
- if ( sscanf( argv[argn++], "%d", &newcols) != 1 )
- pm_usage( usage );
-
- if ( sscanf( argv[argn++], "%d", &newrows) != 1)
- pm_usage( usage );
-
- if ( argn != argc )
- {
- ifd = pm_openr( argv[argn] );
- argn++;
- }
- else
- ifd = stdin;
-
- if ( argn != argc )
- pm_usage( usage );
-
- ppm_pbmmaxval = 255; /* use larger value for better results */
- pixels = ppm_readppm( ifd, &cols, &rows, &maxval );
-
- pm_close( ifd );
-
- ppm_writeppminit( stdout, newcols, newrows, maxval );
- newpixelrow = ppm_allocrow( newcols );
-
- for ( row = 0, irow = 0; row < newrows; row++ )
- {
-
- /* Each destination row consinsts of a repatition of input rows. The source
- * pointer is reset to the starting point every cols pixels. This could also
- * have been done using moduls, i.e. *dP++ = pixels[irow][col % cols], or
- * ultimately *dP++ = pixels[row % rows][col % cols]. I'm not exactly sure
- * which produces the most efficient code.
- */
-
- for ( col = 0, icol = 0, sP = pixels[irow], dP = newpixelrow;
- col < newcols;
- col++ )
- {
- *dP++ = *sP++;
- if (++icol >= cols) /* End of input, reset to start of row */
- {
- icol = 0;
- sP = pixels[irow];
- }
- }
-
- ppm_writeppmrow( stdout, newpixelrow, newcols, maxval );
-
- /* Similar with columns, need to repeat ever "rows" row. */
-
- if (++irow >= rows)
- irow = 0;
- }
-
- exit(0);
- }
- @EOF
-
- chmod 644 ppmfill.c
-
- echo x - ppmborder.c
- cat >ppmborder.c <<'@EOF'
- /* ppmborder - create a border with a tile of a ppm file.
- **
- ** Written 3/90 by Bill Turner, heavily leveraged from code by Jef Poskanzer,
- ** hence the copyright below.
- **
- ** Copyright (C) 1989 by Jef Poskanzer.
- **
- ** Permission to use, copy, modify, and distribute this software and its
- ** documentation for any purpose and without fee is hereby granted, provided
- ** that the above copyright notice appear in all copies and that both that
- ** copyright notice and this permission notice appear in supporting
- ** documentation. This software is provided "as is" without express or
- ** implied warranty.
- */
-
- #include <stdio.h>
- #include "ppm.h"
-
- main( argc, argv )
- int argc;
- char *argv[];
- {
- FILE *ifd, *borderfd;
- pixel **pixels, **borderpixels, *newpixelrow;
- register pixel *sP, *dP, *bP;
- int argn, rows, cols, row, col;
- int brows, bcols, brow, bcol, border, newcols;
- pixval maxval;
- char *usage = "width ppmfile [ppmfile]";
-
- pm_progname = argv[0];
-
- argn = 1;
-
- if ( argc < 3 )
- pm_usage( usage );
-
- if ( sscanf( argv[argn++], "%d", &border) != 1 )
- pm_usage( usage );
-
-
- if ( argn != argc )
- {
- borderfd = pm_openr( argv[argn] );
- argn++;
- }
- else
- pm_usage( usage );
-
- if ( argn != argc )
- {
- ifd = pm_openr( argv[argn] );
- argn++;
- }
- else
- ifd = stdin;
-
- if ( argn != argc )
- pm_usage( usage );
-
- ppm_pbmmaxval = 255; /* use larger value for better results */
- borderpixels = ppm_readppm( borderfd, &brows, &bcols, &maxval);
- pm_close( borderfd );
-
- pixels = ppm_readppm( ifd, &cols, &rows, &maxval );
- pm_close( ifd );
- newcols = cols + border * 2; /* New width includes left and right border */
-
- ppm_writeppminit( stdout, newcols, rows + border * 2, maxval );
- newpixelrow = ppm_allocrow( newcols );
-
- /* For the topborder rows, simply tile from the border ppm. */
- /* (See the ppmfill code for a description of the tiling and possible
- * changes.)
- */
-
- for ( row = 0, brow = 0; row < border; row++ )
- {
- for ( col = 0, bcol = 0, dP = newpixelrow, bP = borderpixels[brow];
- col < newcols;
- col++)
- {
- *dP++ = *bP++;
- if ( ++bcol >= bcols )
- {
- bcol = 0;
- bP = borderpixels[brow];
- }
- }
-
- ppm_writeppmrow( stdout, newpixelrow, newcols, maxval );
-
- if ( ++brow >= brows )
- brow = 0;
- }
-
- /* For the "middle" rows, first copy the left border bits from the tile, then
- * copy the image row, then the right border bits from the tile.
- */
-
- for ( row = 0; row < rows; row++ )
- {
-
- /* Left border */
- for ( col = 0, bcol = 0, dP = newpixelrow, bP = borderpixels[brow];
- col < border;
- col++ )
- {
- *dP++ = *bP++;
- if ( ++bcol >= bcols )
- {
- bcol = 0;
- bP = borderpixels[brow];
- }
- }
-
- /* Image bits */
- for ( col = 0, sP = pixels[row];
- col < cols;
- col++ )
- {
- *dP++ = *sP++;
- }
-
- /* Right border */
- bcol = (cols + border) % bcols;
- for ( col = 0, bP = &borderpixels[brow][bcol];
- col < border;
- col++ )
- {
- *dP++ = *bP++;
- if ( ++bcol >= bcols )
- {
- bcol = 0;
- bP = borderpixels[brow];
- }
- }
-
- ppm_writeppmrow( stdout, newpixelrow, newcols, maxval );
- if (++brow >= brows)
- brow = 0;
- }
-
- /* As with the top border, so with the bottom border. */
-
- for ( row = 0; row < border; row++ )
- {
- for ( col = 0, bcol = 0, dP = newpixelrow, bP = borderpixels[brow];
- col < cols + border * 2;
- col++)
- {
- *dP++ = *bP++;
- if ( ++bcol >= bcols )
- {
- bcol = 0;
- bP = borderpixels[brow];
- }
- }
-
- ppm_writeppmrow( stdout, newpixelrow, newcols, maxval );
-
- if ( ++brow >= brows )
- brow = 0;
- }
-
- exit(0);
- }
- @EOF
-
- chmod 644 ppmborder.c
-
- echo x - ppmmerge.c
- cat >ppmmerge.c <<'@EOF'
- /* ppmmerge.c - merge two or more portable pixmaps
- **
- ** Written 3/90 by Bill Turner, but leveraged heavily from code by Jef
- ** Poskanzer (extensive use of the PBM code), so the copyright notice is
- ** attached below.
- **
- ** Copyright (C) 1989 by Jef Poskanzer.
- **
- ** Permission to use, copy, modify, and distribute this software and its
- ** documentation for any purpose and without fee is hereby granted, provided
- ** that the above copyright notice appear in all copies and that both that
- ** copyright notice and this permission notice appear in supporting
- ** documentation. This software is provided "as is" without express or
- ** implied warranty.
- */
-
- #include <stdio.h>
- #include "ppm.h"
-
- void WriteStack();
- void WriteSide();
-
- main( argc, argv )
- int argc;
- char *argv[];
- {
- FILE *ifd;
- pixel **pixels, *newpixelrow;
- pixel ***pixel_list;
- register pixel *pP, *npP;
- pixel bgpixel, prevpixel, p;
- int argn, rows, cols, newrows, newcols, row, col, new;
- pixval maxval;
- int *cols_list, *rows_list, *pad_list;
- pixval *maxval_list;
- int num_files;
- char *usage = "[-v | -h] ppmfile...";
- int stack = 0;
- int i;
-
- pm_progname = argv[0];
-
- argn = 1;
-
- /* Create lists for file data (dynamic allocation, since there can be an
- * indeterminate number of files)
- */
-
- pixel_list = (pixel ***) malloc(sizeof(pixel **));
- rows_list = (int *) malloc(sizeof(int));
- cols_list = (int *) malloc(sizeof(int));
- maxval_list = (pixval *) malloc(sizeof(pixval));
-
- if ( argn == argc )
- pm_usage( usage );
-
- if ( strcmp(argv[argn], "-h") == 0 ) {
- stack = 0;
- argn++;
- }
- else if ( strcmp(argv[argn], "-v") == 0) {
- stack = 1;
- argn++;
- }
-
- if ( argn == argc )
- pm_usage( usage );
-
- /* Read all files */
- num_files = 0;
- while ( argn != argc )
- {
- ifd = pm_openr( argv[argn] );
- num_files++;
- argn++;
-
- ppm_pbmmaxval = 255; /* use larger value for better results */
- pixels = ppm_readppm( ifd, &cols, &rows, &maxval );
-
- pm_close( ifd );
-
- /* Copy data to information arrays (realloc to add new record) */
-
- pixel_list = (pixel ***) realloc(pixel_list,
- sizeof(pixel **) * num_files);
- rows_list = (int *) realloc(rows_list, sizeof(int) * num_files);
- cols_list = (int *) realloc(cols_list, sizeof(int) * num_files);
- maxval_list = (pixval *) realloc(maxval_list,
- sizeof(pixval) * num_files);
-
- pixel_list[num_files - 1] = pixels;
- rows_list[num_files - 1] = rows;
- cols_list[num_files - 1] = cols;
- maxval_list[num_files - 1] = maxval;
- }
-
- /* After reading in all the files, find the new width and height. If stack
- * is true, then the images are being stacked on top of each other -- width
- * is the maximum of all widths, height is the sum of the heights. If stack
- * is false, then put images beside each other -- width is the sum of the
- * widths, and height is the sum of the heights.
- */
-
- newcols = newrows = 0;
- for (i = 0; i < num_files; i++)
- {
- if (stack)
- {
- if (newcols < cols_list[i])
- newcols = cols_list[i];
- newrows += rows_list[i];
- }
- else
- {
- if (newrows < rows_list[i])
- newrows = rows_list[i];
- newcols += cols_list[i];
- }
- if (maxval < maxval_list[i])
- maxval = maxval_list[i];
- }
-
- /* Call the appropriate Write routine -- WriteStack, or WriteSide -- to write
- * the merged PPM file.
- */
-
- if (stack)
- {
-
- /* Find the left-side padding for each file first */
-
- pad_list = (int *) malloc(sizeof(int) * num_files);
- for (i = 0; i < num_files; i++)
- if (cols_list[i] < newcols)
- pad_list[i] = (newcols + 1 - cols_list[i]) / 2;
- else
- pad_list[i] = 0;
-
- WriteStack(pixel_list, cols_list, rows_list, pad_list,
- newcols, newrows, maxval, num_files);
- }
- else
- {
-
- /* Find the top-side padding for each file first */
-
- pad_list = (int *) malloc(sizeof(int) * num_files);
- for (i = 0; i < num_files; i++)
- if (rows_list[i] < newrows)
- pad_list[i] = (newrows + 1 - rows_list[i]) / 2;
- else
- pad_list[i] = 0;
- WriteSide(pixel_list, cols_list, rows_list, pad_list,
- newcols, newrows, maxval, num_files);
- }
-
- exit(0);
- }
-
-
- /* WriteStack writes each image, one on top of each other. Simply write out
- * each image sequentially, with padding as required to get a consistent
- * width.
- */
-
- void WriteStack(pix_list, cols_list, rows_list, pad_list,
- newcols, newrows, maxval, count)
- pixel ***pix_list;
- int *cols_list;
- int *rows_list;
- int *pad_list;
- int newcols;
- int newrows;
- pixval maxval;
- int count;
- {
- int file, col, row;
- pixel *newrow, *srcP, *destP, bgpixel;
-
- ppm_writeppminit( stdout, newcols, newrows, maxval );
- newrow = ppm_allocrow(newcols);
-
- for (file = 0; file < count; file++)
- {
-
- /* Calculate the background pixel to use for filling (if pad is non-zero) */
-
- bgpixel = ppm_backgroundpixel(pix_list[file],
- cols_list[file],
- rows_list[file]);
- for (row = 0; row < rows_list[file]; row++)
- {
- destP = newrow;
- srcP = pix_list[file][row];
- for( col = 0; col < pad_list[file]; col++ ) /* Add left pad */
- *destP++ = bgpixel;
-
- for(col = 0; col < cols_list[file]; col++)
- *destP++ = *srcP++;
-
- for(col = cols_list[file]; col < newcols - pad_list[file]; col++)
- *destP++ = bgpixel; /* Add right pad */
-
- ppm_writeppmrow( stdout, newrow, newcols, maxval );
- }
- }
- }
-
-
- /* WriteSide writes the images side-by-side. This requires appending scan
- * lines from each file together to produce an output scanline. Also requires
- * adding a blank scanline for top and bottom padding to get a consistent
- * height.
- */
-
- void WriteSide(pix_list, cols_list, rows_list, pad_list,
- newcols, newrows, maxval, count)
- pixel ***pix_list;
- int *cols_list;
- int *rows_list;
- int *pad_list;
- int newcols;
- int newrows;
- pixval maxval;
- int count;
- {
- int file, col, row;
- pixel *newrow, *srcP, *destP, bgpixel;
-
- ppm_writeppminit( stdout, newcols, newrows, maxval );
- newrow = ppm_allocrow(newcols);
-
- for (row = 0; row < newrows; row++)
- {
- destP = newrow;
- for (file = 0; file < count; file++)
- {
-
- /* Check to see if we are in the pad region, either top or bottom. */
-
- if ((row < pad_list[file]) ||
- (row >= rows_list[file] + pad_list[file]))
- {
-
- /* Fill with the background pixel for a pad. */
-
- bgpixel = ppm_backgroundpixel( pix_list[file],
- cols_list[file],
- rows_list[file] );
- for (col = 0; col < cols_list[file]; col++)
- *destP++ = bgpixel;
- }
- else
- {
-
- /* Copy the appropriate source row (absolute row number minus the number of
- * padding rows required).
- */
-
- srcP = pix_list[file][row - pad_list[file]];
- for (col = 0; col < cols_list[file]; col++)
- *destP++ = *srcP++;
- }
- }
-
- ppm_writeppmrow( stdout, newrow, newcols, maxval );
- }
- }
- @EOF
-
- chmod 644 ppmmerge.c
-
- echo x - ppmoverlay.c
- cat >ppmoverlay.c <<'@EOF'
- /* ppmoverlay - overlay one ppm file over the top of another.
- **
- ** Written 3/90 by Bill Turner, heavily leveraged from code by Jef Poskanzer,
- ** hence the copyright below.
- **
- ** Copyright (C) 1989 by Jef Poskanzer.
- **
- ** Permission to use, copy, modify, and distribute this software and its
- ** documentation for any purpose and without fee is hereby granted, provided
- ** that the above copyright notice appear in all copies and that both that
- ** copyright notice and this permission notice appear in supporting
- ** documentation. This software is provided "as is" without express or
- ** implied warranty.
- */
-
- #include <stdio.h>
- #include "ppm.h"
-
- #define UNSPECIFIED 0
- #define LEFT 1
- #define CENTER 2
- #define RIGHT 3
-
- #define TOP 1
- #define BOTTOM 3
-
- main( argc, argv )
- int argc;
- char *argv[];
- {
- FILE *ifd, *bfd;
- pixel **pixels, **backpixels, *newpixelrow;
- register pixel *sP, *bP, *dP;
- int argn, rows, cols, backrows, backcols, row, col;
- int topborder, bottomborder, leftborder, rightborder, minborder;
- int brow, bcol;
- int valign, halign;
- pixval maxval, backmax;
- char *usage = "[-top | -vcenter | -bottom] [-left | -hcenter |
- -right] [-border #] ppmfile [ppmbackground]";
-
- pm_progname = argv[0];
-
- argn = 1;
-
- if ( argc < 2 )
- pm_usage( usage );
-
- valign = halign = 0;
- topborder = bottomborder = leftborder = rightborder = minborder = 0;
-
- while ( argn + 1 < argc && argv[argn][0] == '-' )
- {
- if (strcmp(argv[argn], "-top") == 0)
- {
- if ( valign )
- pm_error("only one of -top/-vcenter/-bottom may be specified",
- 0,0,0,0,0);
- valign = TOP;
- }
- else if (strcmp(argv[argn], "-vcenter") == 0)
- {
- if ( valign )
- pm_error("only one of -top/-vcenter/-bottom may be specified",
- 0,0,0,0,0);
- valign = CENTER;
- }
- else if (strcmp(argv[argn], "-bottom") == 0)
- {
- if ( valign )
- pm_error("only one of -top/-vcenter/-bottom may be specified",
- 0,0,0,0,0);
- valign = BOTTOM;
- }
- else if (strcmp(argv[argn], "-left") == 0)
- {
- if ( halign )
- pm_error("only one of -left/-hcenter/-right may be specified",
- 0,0,0,0,0);
- halign = LEFT;
- }
- else if (strcmp(argv[argn], "-hcenter") == 0)
- {
- if ( halign )
- pm_error("only one of -left/-hcenter/-right may be specified",
- 0,0,0,0,0);
- halign = CENTER;
- }
- else if (strcmp(argv[argn], "-right") == 0)
- {
- if ( halign )
- pm_error("only one of -left/-hcenter/-right may be specified",
- 0,0,0,0,0);
- halign = RIGHT;
- }
- else if (strcmp(argv[argn], "-border") == 0)
- {
- if ( sscanf( argv[argn+1], "%d", &minborder) != 1)
- pm_usage( usage );
- if ( minborder < 0)
- pm_error( "border width must be greater than 0", 0,0,0,0,0 );
- argn++;
- }
- else
- pm_usage( usage );
- argn++;
- }
-
- if (argn == argc)
- pm_usage( usage );
-
- ifd = pm_openr( argv[argn] );
- argn++;
-
- if ( argn != argc )
- {
- bfd = pm_openr( argv[argn] );
- argn++;
- }
- else
- bfd = stdin;
-
- if ( argn != argc )
- pm_usage( usage );
-
- ppm_pbmmaxval = 255; /* use larger value for better results */
- pixels = ppm_readppm( ifd, &cols, &rows, &maxval );
-
- pm_close( ifd );
-
- backpixels = ppm_readppm( bfd, &backcols, &backrows, &backmax );
-
- /* Calculate the borders based on valign, halign, and minborder. Also make
- * sure that the overlayed image will fit on the background with the
- * constraints specified.
- */
-
- switch (halign)
- {
- case LEFT:
- leftborder = minborder;
- rightborder = backcols - cols - leftborder;
- break;
-
- case UNSPECIFIED:
- case CENTER:
- leftborder = (backcols - cols + 1) / 2;
- rightborder = backcols - cols - leftborder;
- break;
-
- case RIGHT:
- rightborder = minborder;
- leftborder = backcols - cols - rightborder;
- break;
- }
-
- if ((leftborder < minborder) || (rightborder < minborder))
- pm_error( "picture is too large to overlay. Try larger
- background or smaller border", 0,0,0,0,0);
-
- switch (valign)
- {
- case TOP:
- topborder = minborder;
- bottomborder = backrows - rows - topborder;
- break;
-
- case UNSPECIFIED:
- case CENTER:
- topborder = (backrows - rows + 1) / 2;
- bottomborder = backrows - rows - topborder;
- break;
-
- case BOTTOM:
- bottomborder = minborder;
- topborder = backrows - rows - bottomborder;
- break;
- }
-
- if ((topborder < minborder) || (bottomborder < minborder))
- pm_error( "picture is too large to overlay. Try larger
- background or smaller border", 0,0,0,0,0);
-
-
- ppm_writeppminit( stdout, backcols, backrows, maxval );
- newpixelrow = ppm_allocrow( backcols );
-
- /* For topborder, simply copy the background row to the output. */
-
- for ( row = 0, brow = 0; row < topborder; row++, brow++ )
- {
- for ( col = 0, bP = backpixels[brow], dP = newpixelrow;
- col < backcols;
- col++ )
- *dP++ = *bP++;
-
- ppm_writeppmrow( stdout, newpixelrow, backcols, maxval );
- }
-
- /* For the rows that overlay, copy the left border colmuns from the background,
- * followed by the overlay row, followed by the right border columns from the
- * background.
- */
-
- for ( row = 0; row < rows; row++, brow++ )
- {
- for ( col = 0, bP = backpixels[brow], dP = newpixelrow;
- col < leftborder;
- col++ )
- *dP++ = *bP++;
-
- for ( col = 0, sP = pixels[row];
- col < cols;
- col++, bP++ )
- *dP++ = *sP++;
-
- for ( col = 0; col < rightborder; col++ )
- *dP++ = *bP++;
-
- ppm_writeppmrow( stdout, newpixelrow, backcols, maxval );
- }
-
- /* And, for the bottom border rows, simply copy from the background. */
-
- for ( row = 0; row < bottomborder; row++, brow++ )
- {
- for ( col = 0, bP = backpixels[brow], dP = newpixelrow;
- col < backcols;
- col++ )
- *dP++ = *bP++;
-
- ppm_writeppmrow( stdout, newpixelrow, backcols, maxval );
- }
-
- exit(0);
- }
- @EOF
-
- chmod 644 ppmoverlay.c
-
- exit 0
-
-